﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Reflection;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.Identity;
using QuickPrompt.DomainModel;
using QuickPrompt.Helper;
using QuickPromt.Service;
using RedandBlue.Common.Logging;
using RedandBlue.Plugin.Sms.TextBelt;
using RedandBlue.Plugin.Sms.TextBelt.DataTypes;
using RedandBlue.RepositoryPattern.Repositories;
using RedandBlue.RepositoryService;

namespace QuickPrompt.BusinessService
{
    public  class QuickPromptService: Service<Prompt>, IQuickPromptService
    {
        private readonly IRepositoryAsync<Prompt> _repository;
        public QuickPromptService(IRepositoryAsync<Prompt> repository) : base(repository)
        {
            _repository = repository;
        }

        public bool Email(Prompt promptDetails)
        {
            var message = new MailMessage();
            if (!string.IsNullOrEmpty(promptDetails.AddressValue))
            {
                //To address 
                message.To.Add(new MailAddress(promptDetails.AddressValue));
                message.Subject = $"Quick Prompt about {promptDetails.QuickNote.Name}";

                //Specify true if it is html message
                message.IsBodyHtml = true;

                var executingPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

                var filepath = Path.Combine(executingPath, "templates", "email", "prompt.html");

                string mailBody = File.ReadAllText(filepath);
                mailBody = mailBody.Replace("%User.FirstName%", promptDetails.QuickNote.User.FirstName);
                mailBody = mailBody.Replace("%User.LastName%", promptDetails.QuickNote.User.LastName);
                mailBody = mailBody.Replace("%User.Description%", promptDetails.QuickNote.Description);

                message.Body = mailBody;

                AlternateView htmlView = AlternateView.CreateAlternateViewFromString(mailBody, null, "text/html");
                message.AlternateViews.Add(htmlView);
            }
            return new EmailHelper().Send(message);
        }

        public bool VoiceMail(Prompt promptDetails)
        {
            throw new NotImplementedException();
        }

        public bool Text(Prompt promptDetails)
        {
            Message message = new Message
            {
                Country = Country.UnitedStates,
                MobileNumber = promptDetails.AddressValue,
                TextMessage = promptDetails.QuickNote.Description
            };

            var unitedStatesZone = RedandBlue.Common.Locale.Country.Zones("US");
            var canadaZone = RedandBlue.Common.Locale.Country.Zones("CA");

            if (unitedStatesZone.Any(x=>x.Equals(promptDetails.PromptTimeZone, StringComparison.OrdinalIgnoreCase)))
                message.Country = Country.UnitedStates;
            else if (canadaZone.Any(x => x.Equals(promptDetails.PromptTimeZone, StringComparison.OrdinalIgnoreCase)))
                message.Country = Country.Canada;
            else
                message.Country = Country.International;

            Sms sms = new Sms(message);
            Log.Debug(GetType().FullName, MethodBase.GetCurrentMethod().Name, "Sending text message to {0}", promptDetails.AddressValue);
            try
            {
                sms.Send();
                return true;
            }
            catch (Exception exception)
            {
                Log.Error(GetType().FullName, MethodBase.GetCurrentMethod().Name, exception);
                return false;
            }
        }

        public void QuickPrompt(Prompt prompt)
        {
            switch (prompt.PromptType)
            {
                case PromptType.Email:
                    Email(prompt);
                    break;
                case PromptType.Text:
                    Text(prompt);
                    break;
                case PromptType.Voice:
                    VoiceMail(prompt);
                    break;
            }
        }


        public List<Prompt> Get(int noteId, bool excludeDeleted = true)
        {
            if (excludeDeleted)
                return _repository.Query(p => p.NoteId == noteId && !p.IsDeleted).Select().ToList();

            return _repository.Query(p => p.NoteId == noteId).Select().ToList();
        }

        public void SetToDelete(int id)
        {
            var prompt = base.Query(x => x.Id == id).Select().SingleOrDefault();
            if (prompt == null)
            {
                Log.Error(GetType().FullName, MethodBase.GetCurrentMethod().Name, "No Prompt found with {0}", id);
                return;
            }
            prompt.IsDeleted = true;
            base.Update(prompt);
        }

        public override void Update(Prompt entity)
        {
            var prompt = base.Query(x => x.Id == entity.Id).Select().SingleOrDefault();
            if (prompt == null)
            {
                Log.Error(GetType().FullName, MethodBase.GetCurrentMethod().Name, "No prompt found with {0}", entity.Id);
                return;
            }
            prompt.AddressValue = entity.AddressValue;
            prompt.PromptType = entity.PromptType;
            prompt.PromptTimeZone = entity.PromptTimeZone;
            prompt.PromptFrequency = entity.PromptFrequency;
            prompt.StartingFromUtc = entity.StartingFromUtc.ToUniversalTime();
            prompt.IsActive = entity.IsActive;
            // e.g. add business logic here before inserting
            base.Update(prompt);
        }
        public override void Insert(Prompt entity)
        {
            entity.StartingFromUtc = entity.StartingFromUtc.ToUniversalTime();
            // e.g. add business logic here before inserting
            base.Insert(entity);
        }
    }
}
